<template>
  <div>
    <el-tree :data="menus"
             :props="defaultProps"
             show-checkbox
             node-key="catId"
             :default-expanded-keys="expandedKey"
             :expand-on-click-node="false">
    <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button
            v-if="node.level <= 2"
            type="text"
            size="mini"
            @click="() => append(data)">
            Append
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => edit(data)">
            Edit
          </el-button>
          <el-button
            v-if="node.childNodes.length === 0"
            type="text"
            size="mini"
            @click="() => remove(node, data)">
            Delete
          </el-button>
        </span>
      </span>
    </el-tree>

    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      width="30%">
      <el-form :model="category" ref="categoryForm">
        <el-form-item label="分类名称">
          <el-input v-model="category.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图标">
          <el-input v-model="category.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="计量单位">
          <el-input v-model="category.productUnit" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitData">确 定</el-button>
      </span>
    </el-dialog>
  </div>

</template>

<script>
import {messageTip} from '../../../utils/message'
export default {
  data () {
    return {
      // 弹框标题
      dialogTitle: '',
      // 新增/修改标志
      dialogType: '',
      // 表单（这玩意应该叫categoryForm，而不是category，因为这里定义的所有都要直接给后端）
      category: {
        name: '',
        parentCid: 0,
        catLevel: 0,
        showStatus: 1,
        sort: 0,
        productUnit: '',
        icon: '',
        catId: null
      },
      // 对话框
      dialogVisible: false,
      expandedKey: [],
      menus: [],
      defaultProps: {
        // 返回的内容哪个表示子节点（这里是children）
        children: 'children',
        // 要显示节点的名字对应哪个属性（这里是name）
        label: 'name'
      }
    }
  },

  created () {
    this.getMenus()
  },

  methods: {
    // 获取菜单列表
    getMenus () {
      this.$http({
        url: this.$http.adornUrl('/product/category/list/tree'),
        method: 'get'
      }).then(({data}) => {
        // 这里的花括号就是解构操作
        console.log('菜单列表数据:', data.data)
        messageTip('哈哈，数据拿到了', 'success')
        if (data.code === 0) {
          this.menus = data.data
        } else {
          messageTip(`服务器操作失败!失败原因${data.msg}`, 'error')
        }
      }).catch(() => {
        messageTip('获取数据失败!服务器异常!', 'error')
      })
    },
    // 新增弹窗按钮（这里相当于把后端传的初始数据的某个对象（data）初始给某个表单对象（category），也就是说data的数据是“全”的）
    append (data) {
      console.log('append:', data)
      // 新增标识
      this.dialogType = 'add'
      this.dialogTitle = '新增分类'
      // 先清空之前提交的name（不能直接this.category.name = {}这样会导致默认初始化数据传不到后端）
      // this.category.name = ''
      // 选择直接重新使用初始化数据
      this.category = this.$options.data().category
      // 在这里把对话框表单category的部分数据进行赋值
      this.category.parentCid = data.catId
      // 这里需要注意一下，因为后端返回的是字符串，所以这里需要转换成数字类型
      this.category.catLevel = data.catLevel * 1 + 1
      // 打开对话框
      this.dialogVisible = true
    },
    // 新增分类
    addCategory () {
      console.log('需要提交的数据', this.category)
      this.$http({
        url: this.$http.adornUrl('/product/category/save'),
        method: 'post',
        data: this.$http.adornData(this.category)
      }).then(({data}) => {
        console.log('后端返回:', data)
        if (data.code === 0) {
          messageTip('菜单添加成功!', 'success')
          // 关闭弹窗
          this.dialogVisible = false
          // 刷新页面
          this.getMenus()
          // 设置要展示的节点
          this.expandedKey = [this.category.parentCid]
        } else {
          messageTip(`服务器操作失败!失败原因${data.msg}`, 'error')
        }
      }).catch(() => {
        messageTip('获取数据失败!服务器异常!', 'error')
      })
    },
    // 编辑弹窗按钮
    edit (data) {
      console.log('需要编辑的数据:', data)
      // 修改标识
      this.dialogType = 'edit'
      this.dialogTitle = '修改分类'
      // 初始化要编辑的数据（按之前的写法是传一个id给后端，单查这个数据回显，现在直接拿最初列表查询的结果了）
      // this.category.name = data.name 不请求后端直接这样做在并发环境多用户操作同一个数据时会有问题
      this.$http({
        url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
        method: 'get'
      }).then(({data}) => {
        console.log('后端返回:', data)
        if (data.code === 0) {
          messageTip('获取节点信息成功!', 'success')
          // this.category.name = data.nam 老师是这样写的，不知道用意何在（说是后面有拖拽功能要用）
          this.category = data.data
        } else {
          messageTip(`服务器操作失败!失败原因${data.msg}`, 'error')
        }
      }).catch(() => {
        messageTip('获取数据失败!服务器异常!', 'error')
      })
      this.dialogVisible = true
    },
    // 编辑节点
    editCategory () {
      console.log('需要提交的数据（已编辑好的）', this.category)
      // 这里如果不想把整个this.category都给后端，可以使用解构的写法给后端data即可（有省略写法）
      // （因为这里renren项目没有使用VO和DTO。所以对报文数据没要求，正常情况下是有要求的）
      /* let {catId, name, icon, productUnit} = this.category
      let data = {catId: catId, name: name, icon: icon, productUnit: productUnit} */
      this.$http({
        url: this.$http.adornUrl('/product/category/update'),
        method: 'put',
        data: this.$http.adornData(this.category)
      }).then(({data}) => {
        console.log('后端返回:', data)
        if (data.code === 0) {
          messageTip('菜单编辑成功!', 'success')
          // 关闭弹窗
          this.dialogVisible = false
          // 刷新页面
          this.getMenus()
          // 设置要展示的节点
          this.expandedKey = [this.category.parentCid]
        } else {
          messageTip(`服务器操作失败!失败原因${data.msg}`, 'error')
        }
      }).catch(() => {
        messageTip('获取数据失败!服务器异常!', 'error')
      })
    },
    // 因为表单复用，所以在这里进行判断是走新增还是修改
    submitData () {
      if (this.dialogType === 'add') {
        // 新增操作
        this.addCategory()
      }
      if (this.dialogType === 'edit') {
        // 修改操作
        this.editCategory()
      }
    },
    // 删除
    remove (node, data) {
      // node 是当前节点对象的信息（也就是el组件的信息），data 是当前节点数据（也就是实际上后端返回的数据）
      // 注意这里的写法，是逗号隔开
      console.log('remove:', node, 'data:', data)
      // 把当前节点数据中的catId属性值，赋给ids数组，当前是单独删除一个
      let ids = [data.catId]
      this.$confirm(`是否删除【${data.name}】菜单?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$http({
          url: this.$http.adornUrl('/product/category/delete'),
          method: 'delete',
          data: this.$http.adornData(ids, false)
        }).then(({data}) => {
          if (data.code === 0) {
            messageTip('菜单删除成功', 'success')
            // 刷新页面
            this.getMenus()
            // 展示当前节点的父节点id
            // 效果一样this.expandedKey[0] = node.parent.data.catId
            this.expandedKey = [node.parent.data.catId]
          } else {
            messageTip(`服务器操作失败!失败原因${data.msg}`, 'error')
          }
        })
      }).catch(() => {
        messageTip('已取消删除')
      })
    }
  }
}
</script>

<style scoped>

</style>
